import WebpackLicense from '@components/WebpackLicense';
import { ApiMeta, Stability } from '../../../components/ApiMeta';
import PropertyType from '@components/PropertyType';

<WebpackLicense from="https://webpack.docschina.org/configuration/entry-context/#entry" />

# Entry

<PropertyType
  type="string | string[] | Record<string, string | string[] | EntryDescription> | Function"
  defaultValueList={[{ defaultValue: "'./src/index.js'" }]}
/>

入口：该选项用于设置 Rspack 构建的入口。

## 单个入口

当你构建一个单页面应用（SPA），或是构建一个库时，通常只需要设置单个入口。

设置单个入口时，直接将入口模块的路径作为字符串传入 `entry` 配置项即可。

```js title="rspack.config.mjs"
export default {
  entry: './src/index.js',
};
```

以上写法会自动将入口模块的名称设置为 `main`，等价于以下写法：

```js title="rspack.config.mjs"
export default {
  entry: {
    main: './src/index.js',
  },
};
```

### 路径类型

入口模块的路径可以是一个相对路径，也可以是一个绝对路径。

当 `entry` 被设置为相对路径时，Rspack 会使用 [context 配置项](/config/context.html) 设置的值作为基础路径，默认为 Node.js 进程的当前工作目录，即 `process.cwd()`。

你也可以使用 Node.js 中的 [path 模块](https://nodejs.org/api/path.html) 来生成一个绝对路径，并传递给 `entry` 配置项：

```js title="rspack.config.mjs"
import path from 'node:path';

export default {
  entry: path.join(__dirname, './src/index.js'),
};
```

### 入口数组

在设置入口的值时，除了设置为 `string`，你也可以传入一个 `string[]`，这代表该入口中包含多个入口模块。

比如以下示例，会将 `pre.js` 和 `post.js` 构建到 `page` 的产物中。

```js title="rspack.config.mjs"
export default {
  entry: {
    page: ['./src/pre.js', './src/post.js'],
  },
};
```

多个模块会按照数组定义的顺序依次执行，因此 `pre.js` 的代码会早于 `post.js` 的代码执行。

## 多个入口

当你需要同时构建多个入口时，你需要将 `entry` 设置为一个对象，对象的每一个 key 对应一个入口名称。

比如以下示例，会将 `page1` 和 `page2` 作为两个入口进行构建：

```js title="rspack.config.mjs"
export default {
  entry: {
    page1: './src/page1/index.js',
    page2: './src/page2/index.js',
  },
};
```

### 入口描述对象

当你将 `entry` 设置为一个对象时，可以将入口的值设置为一个描述对象。描述对象可以包含以下属性：

#### EntryDescription.import

<PropertyType
  type="string[] | string"
  defaultValueList={[{ defaultValue: "'./src/index.js'" }]}
/>

一个或多个入口模块的路径。

```js title="rspack.config.mjs"
export default {
  entry: {
    foo: {
      import: './src/foo.js',
    },
  },
};
```

`import` 属性可以设置多个路径：

```js title="rspack.config.mjs"
export default {
  entry: {
    foo: {
      import: ['./src/foo.js', './src/bar.js'],
    },
  },
};
```

#### EntryDescription.runtime

<PropertyType
  type="false | string"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

运行时 chunk 的名称。设置 `runtime` 后，会创建一个新的运行时 chunk。你也可以将它设置为 `false` 来避免一个新的运行时 chunk。

`runtime` 属性用于设置运行时 `chunk` 的名称，比如将 `main` 入口的 chunk 名称设置为 `'foo'`：

```js title="rspack.config.mjs"
export default {
  entry: {
    main: {
      import: './src/index.js',
      runtime: 'foo',
    },
  },
};
```

#### EntryDescription.chunkLoading

<PropertyType
  type="false | string | 'jsonp' | 'import-scripts' | 'require' | 'async-node' | 'import'"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

设置当前入口在加载 chunk 时的加载方式。默认包含的方式有 `'jsonp'` (web), `'import'` (ESM), `'import-scripts'` (WebWorker), `'require'` (sync node.js), `'async-node'` (async node.js)，其他方式可由插件提供。

#### EntryDescription.asyncChunks

<PropertyType type="boolean" defaultValueList={[{ defaultValue: 'true' }]} />

是否为当前入口创建按需加载的异步 chunk。

#### EntryDescription.publicPath

<PropertyType
  type="'auto' | string | (pathData: PathData, assetInfo?: AssetInfo) => string"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

修改当前入口引用的资源的 publicPath。

#### EntryDescription.baseUri

<PropertyType
  type="string"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

修改当前入口引用的资源的 baseURI。

#### EntryDescription.filename

<PropertyType
  type="string"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

修改当前入口所生成 chunk 的文件名。

#### EntryDescription.library

<PropertyType
  type="string | string[] | object"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

修改当前入口所生成 chunk 作为库的导出格式，详细配置可参考 [output.library](/config/output#outputlibrary)。

#### EntryDescription.dependOn

<PropertyType
  type="string[] | string"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

设置当前入口所依赖的入口。使用 `dependOn` 选项你可以与另一个入口 chunk 共享模块。

#### EntryDescription.wasmLoading

<PropertyType
  type="'fetch' | 'async-node'"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

设置当前入口加载 WebAssembly 模块的方式。默认可使用的方式有 `'fetch'`（web/WebWorker），`'async-node'`（Node.js），其他额外方式可由插件提供。

其默认值会根据 [target](/config/target) 的变化而变化：

- 如果 target 设置为 `'web'`，`'webworker'`，`'electron-renderer'` 或 `'node-webkit'` 其中之一，其默认值为 `'fetch'`。
- 如果 target 设置为 `'node'`，`'async-node'`，`'electron-main'` 或 `'electron-preload'`，其默认值为 `'async-node'`。

#### EntryDescription.layer

<ApiMeta addedVersion={'1.0.0-beta.1'} />

<PropertyType
  type="string | null | undefined"
  defaultValueList={[{ defaultValue: 'undefined' }]}
/>

指定当前入口的模块所在的 layer。用于在 split chunks, [rules](/config/module#ruleissuerlayer)、stats、externals 中通过 layer 匹配使对应的配置生效。

更多关于 layer 的信息，请参考 [Layer 指南](/guide/features/layer)。

:::warning
对于 v1.6.0 之前的版本，只有在 [experiments.layers = true](/config/experiments#experimentslayers) 时该配置才会生效。
:::

```js title="rspack.config.mjs"
export default {
  entry: {
    index: {
      import: './src/index.js',
      layer: 'layer-name',
    },
  },
};
```

## 动态入口

如果传入一个函数，那么它将会在每次 [make](/api/plugin-api/compiler-hooks#make) 事件中被调用。

> 要注意的是，`make` 事件在 webpack 启动和每当[监听文件变化](/config/watch)时都会触发。

```js title="rspack.config.mjs"
export default {
  //...
  entry: () => './demo',
};
```

或者：

```js title="rspack.config.mjs"
export default {
  //...
  entry: () => new Promise(resolve => resolve(['./demo', './demo2'])),
};
```

例如，你可以使用动态入口来从外部来源（远程服务器，文件系统内容或者数据库）获取真正的入口：

```js title="rspack.config.mjs"
export default {
  entry() {
    return fetchPathsFromSomeExternalSource(); // 返回一个会被用像 ['src/main-layout.js', 'src/admin-layout.js'] 的东西 resolve 的 promise
  },
};
```

当和 [output.library](/config/output#outputlibrary) 选项结合：如果传入的是一个数组，只有数组的最后一个条目会被导出。
